package com.ffcs.crmd.tsp.server.job.service;

import java.util.Date;

import org.apache.commons.lang3.StringUtils;
import org.quartz.JobExecutionException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.ffcs.crmd.tsp.api.dto.enu.JobRunExceptionType;
import com.ffcs.crmd.tsp.api.dto.netty.RemotingCommand;
import com.ffcs.crmd.tsp.api.netty.INettyInvokeCallback;
import com.ffcs.crmd.tsp.common.constant.LoggerName;
import com.ffcs.crmd.tsp.common.netty.ResponseCode;
import com.ffcs.crmd.tsp.core.util.XmlUtil;
import com.ffcs.crmd.tsp.server.application.ApplicationManagerHolder;
import com.ffcs.crmd.tsp.server.job.info.JobDetailShell;
import com.ffcs.crmd.tsp.server.manager.JobProcessManager;
import com.ffcs.crmd.tsp.server.netty.task.TaskRegisterInfo;

import io.netty.channel.Channel;

/**
 * 
 * 功能说明:任务执行请求已被接收回调方法
 *
 * @author ZHONGFUHUA
 * 
 * @since 1.0.0-SNAPSHOT
 *
 */
public class JobRecivedCallBackService implements INettyInvokeCallback {
    
    /**
     * 日志
     */
    private final static Logger LOG               = LoggerFactory.getLogger(LoggerName.ServerLoggerName);
    
    /**
     * 通道
     */
    private Channel             channel;
    
    /**
     * 执行端注册信息
     */
    private TaskRegisterInfo    taskRegisterInfo;
    
    /**
     * 子任务运行信息
     */
    private JobDetailShell      jobDetailShell;
    
    /**
     * 子任务缓存处理类
     */
    private JobProcessManager   jobProcessManager = ApplicationManagerHolder.getBean("jobProcessManager", JobProcessManager.class);
    
    public JobRecivedCallBackService(JobDetailShell jobDetailShell, Channel channel, TaskRegisterInfo taskRegisterInfo) {
        this.channel = channel;
        this.taskRegisterInfo = taskRegisterInfo;
        this.jobDetailShell = jobDetailShell;
    }
    
    @Override
    public void operationComplete(RemotingCommand responseCommand) {
        if (taskRegisterInfo != null && StringUtils.isNoneBlank(taskRegisterInfo.getVersion())) {
            LOG.debug("SERVER-NETTY: return a recived jobdetail response that jobKey=[{}], id=[{}], opaque=[{}].",
                jobDetailShell.getContext().getTspJobInstance().getJobKey(), jobDetailShell.getId(), jobDetailShell.getRemotingOpaque());
            jobDetailShell.updateReciveTime(new Date());
            jobProcessManager.updateReciveStatus(this.channel, jobDetailShell);
        } else {
            switch (responseCommand.getCode()) {
                case ResponseCode.SUCCESS:
                    jobProcessManager.completeJobDetail(jobDetailShell.getJobName(), channel, jobDetailShell.getJobDetailName(), jobDetailShell.getId());
                    LOG.debug("SERVER-NETTY: return a complete jobdetail response that jobKey=[{}], id=[{}], opaque=[{}].",
                        jobDetailShell.getContext().getTspJobInstance().getJobKey(), jobDetailShell.getId(), jobDetailShell.getRemotingOpaque());
                    break;
                case ResponseCode.EXCEPTION:
                    JobRunExceptionType jobRunExceptionType = (JobRunExceptionType) XmlUtil.fromXml(new String(responseCommand.getBody()),
                        JobRunExceptionType.class);
                    JobExecutionException jee = new JobExecutionException();
                    if (jobRunExceptionType == JobRunExceptionType.REFIRE_JOB) {
                        jee.setRefireImmediately(true);
                    }
                    jobProcessManager.completeJobDetail(jobDetailShell.getJobName(), channel, jobDetailShell.getJobDetailName(), jobDetailShell.getId(), jee);
                    LOG.warn("SERVER-NETTY: return a complete exception response that jobKey=[{}], id=[{}], opaque=[{}], refire=[{}].",
                        jobDetailShell.getContext().getTspJobInstance().getJobKey(), jobDetailShell.getId(), jobDetailShell.getRemotingOpaque(),
                        jobRunExceptionType);
                    break;
            }
        }
    }
}
